#define _DEFAULT_SOURCE
#include "clog.h"
#include "config.h"
#include "common.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <stdarg.h>
#include <pthread.h>
#include <errno.h>

// 全局变量
static int g_client_socket = -1;
static char g_process_name[MAX_PROCESS_NAME_LEN] = {0};
static int g_initialized = 0;
static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
static char g_config_path[MAX_PATH_LEN] = "log_config.conf";
static log_config_t g_config;
static shared_log_buffer_t g_buffer;

// 内部函数声明
static int connect_to_server(void);
static int init_buffer(void);
static void cleanup_buffer(void);
static int flush_buffer(void);
static int add_to_buffer(const log_message_t* msg);

// 初始化日志缓存
static int init_buffer(void) {
    return init_shared_log_buffer(&g_buffer, g_config.buffer_size);
}

// 清理日志缓存
static void cleanup_buffer(void) {
    if (g_buffer.messages) {
        flush_buffer(); // 刷新剩余的日志
        cleanup_shared_log_buffer(&g_buffer);
    }
}

// 添加消息到缓存
static int add_to_buffer(const log_message_t* msg) {
    pthread_mutex_lock(&g_buffer.mutex);
    
    // 如果缓存已满或者超过刷新间隔，先刷新
    if (g_buffer.count >= g_buffer.capacity || 
        (time(NULL) - g_buffer.last_flush) >= g_config.flush_interval) {
        flush_buffer();
    }
    
    // 添加到缓存
    int index = (g_buffer.head + g_buffer.count) % g_buffer.capacity;
    g_buffer.messages[index] = *msg;
    g_buffer.count++;
    
    pthread_mutex_unlock(&g_buffer.mutex);
    return 0;
}

// 刷新缓存到服务器
static int flush_buffer(void) {
    if (g_buffer.count == 0) {
        return 0;
    }
    
    // 检查连接是否有效
    if (g_client_socket == -1) {
        if (connect_to_server() != 0) {
            return -1;
        }
    }
    
    // 发送所有缓存的消息
    for (int i = 0; i < g_buffer.count; i++) {
        int index = (g_buffer.head + i) % g_buffer.capacity;
        ssize_t sent = send(g_client_socket, &g_buffer.messages[index], 
                           sizeof(log_message_t), 0);
        if (sent == -1) {
            // 发送失败，关闭连接
            close(g_client_socket);
            g_client_socket = -1;
            return -1;
        }
    }
    
    // 重置缓存
    g_buffer.count = 0;
    g_buffer.head = 0;
    g_buffer.last_flush = time(NULL);
    
    return 0;
}

// 连接到服务器
static int connect_to_server(void) {
    // 创建socket
    g_client_socket = socket(AF_UNIX, SOCK_STREAM, 0);
    if (g_client_socket == -1) {
        return -1;
    }
    
    struct sockaddr_un server_addr;
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sun_family = AF_UNIX;
    strcpy(server_addr.sun_path, g_config.socket_path);
    
    // 连接到服务器
    if (connect(g_client_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1) {
        close(g_client_socket);
        g_client_socket = -1;
        return -1;
    }
    
    return 0;
}

// 公共API实现
int clog_init(void) {
    pthread_mutex_lock(&g_mutex);
    
    if (g_initialized) {
        pthread_mutex_unlock(&g_mutex);
        return 0; // 已经初始化
    }
    
    // 加载配置
    if (load_log_config(g_config_path, &g_config) != 0) {
        pthread_mutex_unlock(&g_mutex);
        return -1;
    }
    
    // 获取进程名
    get_process_name_safe(g_process_name, sizeof(g_process_name));
    
    // 初始化缓存
    if (init_buffer() != 0) {
        pthread_mutex_unlock(&g_mutex);
        return -1;
    }
    
    // 连接到服务器
    if (connect_to_server() != 0) {
        cleanup_buffer();
        pthread_mutex_unlock(&g_mutex);
        return -1;
    }
    
    g_initialized = 1;
    pthread_mutex_unlock(&g_mutex);
    return 0;
}

void clog_cleanup(void) {
    pthread_mutex_lock(&g_mutex);
    
    cleanup_buffer();
    
    if (g_client_socket != -1) {
        close(g_client_socket);
        g_client_socket = -1;
    }
    
    g_initialized = 0;
    pthread_mutex_unlock(&g_mutex);
}

int clog_send(clog_level_t level, const char* format, ...) {
    if (!format) {
        return -1;
    }
    
    // 检查日志级别过滤
    if (!should_log_level(level, g_config.min_log_level)) {
        return 0; // 忽略低级别日志
    }
    
    pthread_mutex_lock(&g_mutex);
    
    // 检查是否已初始化
    if (!g_initialized) {
        // 尝试自动初始化
        if (clog_init() != 0) {
            // 初始化失败，但仍然进行控制台输出（如果启用）
            if (g_config.console_output) {
                log_message_t msg;
                msg.level = level;
                get_process_name_safe(msg.process_name, sizeof(msg.process_name));
                get_current_timestamp(msg.timestamp, sizeof(msg.timestamp));
                
                // 格式化消息
                va_list args;
                va_start(args, format);
                vsnprintf(msg.message, sizeof(msg.message), format, args);
                va_end(args);
                
                print_log_to_console(&msg, 1); // 启用颜色
            }
            pthread_mutex_unlock(&g_mutex);
            return -1; // 返回失败，但已输出到控制台
        }
    }
    
    log_message_t msg;
    msg.level = level;
    strcpy(msg.process_name, g_process_name);
    get_current_timestamp(msg.timestamp, sizeof(msg.timestamp));
    
    // 格式化消息
    va_list args;
    va_start(args, format);
    vsnprintf(msg.message, sizeof(msg.message), format, args);
    va_end(args);
    
    // 控制台输出（如果启用）
    if (g_config.console_output) {
        print_log_to_console(&msg, 1); // 启用颜色
    }
    
    // 添加到缓存
    int result = add_to_buffer(&msg);
    
    pthread_mutex_unlock(&g_mutex);
    return result;
}

int clog_is_initialized(void) {
    int result;
    pthread_mutex_lock(&g_mutex);
    result = g_initialized;
    pthread_mutex_unlock(&g_mutex);
    return result;
}

int clog_get_process_name(char* buffer, size_t size) {
    if (!buffer || size == 0) {
        return -1;
    }
    
    pthread_mutex_lock(&g_mutex);
    
    if (!g_initialized) {
        get_process_name_safe(buffer, size);
    } else {
        strncpy(buffer, g_process_name, size - 1);
        buffer[size - 1] = '\0';
    }
    
    pthread_mutex_unlock(&g_mutex);
    return 0;
}

int clog_set_config_path(const char* config_path) {
    if (!config_path) {
        return -1;
    }
    
    pthread_mutex_lock(&g_mutex);
    strncpy(g_config_path, config_path, sizeof(g_config_path) - 1);
    g_config_path[sizeof(g_config_path) - 1] = '\0';
    pthread_mutex_unlock(&g_mutex);
    
    return 0;
}

// 手动刷新缓存
int clog_flush(void) {
    if (!g_initialized) {
        return -1;
    }
    
    pthread_mutex_lock(&g_buffer.mutex);
    int result = flush_buffer();
    pthread_mutex_unlock(&g_buffer.mutex);
    
    return result;
}
